package com.ccf.business.etl.flow;

import cn.hutool.core.text.csv.CsvData;
import cn.hutool.core.text.csv.CsvReader;
import cn.hutool.core.text.csv.CsvRow;
import cn.hutool.core.text.csv.CsvUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSON;
import com.component.api.constants.ComponentCodeConstants;
import com.component.api.constants.ComponentConstants;
import com.component.api.model.dto.FileCenterConfigDTO;
import com.component.api.model.flow.NodeInfo;
import com.common.utils.constant.Constants;
import com.framework.minio.config.MinioConfig;
import com.framework.minio.service.MinioService;
import com.common.model.exception.ParamFomatException;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 描述：
 *
 * @author xianggj
 * @Date 2021/11/30 15:15
 **/
public class FileReadParamHandler extends ParamHandler {


    @Override
    protected Map<String, String> finishingParam() {
        Map<String, String> params = getParams();
        String file = params.get(ComponentConstants.FILE);
        params.put(ComponentConstants.PATH, file);
        String header = params.get(ComponentConstants.HEADER);
        Boolean isHeader = isHeader(header);
        params.put(ComponentConstants.IS_FIRST_LINE, isHeader.toString());
        String suf = StrUtil.subAfter(file, Constants.DOT, true);
        if (ComponentConstants.CSV.equalsIgnoreCase(suf)){
            nodeDTO.setCode(ComponentCodeConstants.CSV_PARSING);
            try {
                String encoding = params.get(ComponentConstants.ENCODING);
                InputStream fileStream = minioService.getFileStream(file);

                List<String> headers = getHeader(fileStream, encoding, isHeader);
                params.put(ComponentConstants.HEADER, JSON.toJSONString(headers));
            } catch (Exception e) {
                e.printStackTrace();
                throw new ParamFomatException("文件读取异常");
            }

        }else if (ComponentConstants.XLS.equalsIgnoreCase(suf) || ComponentConstants.XLSX.equalsIgnoreCase(suf)){
            try {
                InputStream fileStream = minioService.getFileStream(file);
                List<String> headers = getHeader(fileStream, isHeader);
                params.put(ComponentConstants.HEADER, JSON.toJSONString(headers));
            } catch (Exception e) {
                e.printStackTrace();
                throw new ParamFomatException("文件读取异常");
            }
            nodeDTO.setCode(ComponentCodeConstants.XLS_PARSING);
        }
        params.put(ComponentConstants.TYPE, suf);
        params.put(ComponentConstants.CONFIG, JSON.toJSONString(
                new FileCenterConfigDTO(minioConfig.getEndpoint(), minioConfig.getAccessKey(), minioConfig.getSecretKey())));
        return params;
    }

    /**
     * 是否为表头
     * @param header
     * @return
     */
    public  Boolean isHeader(String header) {
        return Boolean.valueOf(FileCenterConfigDTO.HEADER.equalsIgnoreCase(header));
    }

    /**
     * excle查询表头
     * @param inputStream
     * @param isHeader
     * @return
     */
    public  List<String> getHeader(InputStream inputStream, Boolean isHeader) {
        List<String> headers = new ArrayList<>();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        List<Object> objects = reader.readRow(0);
        if (isHeader) {
            headers = objects.stream().map(e->String.valueOf(e)).collect(Collectors.toList());
        } else {
            for (int i = 0; i < objects.size(); i++) {
                headers.add(ComponentConstants.COLUMN_PREFIX + (i+1));
            }
        }
        return headers;
    }

    /**
     * csv获取文件头
     */
    public List<String> getHeader(InputStream inputStream, String encoding, boolean isHeader) {
        CsvReader csvReader = CsvUtil.getReader();
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream,
                Charset.forName(encoding));
        CsvData read = csvReader.read(inputStreamReader);
        List<CsvRow> rows = read.getRows();
        //默认当第一行为列名
        CsvRow headerRow = rows.get(0);
        List<String> headList = headerRow.getRawList();
        List<String> header = new ArrayList<>();
        if (headList == null || headList.size() == 0){
            return header;
        } else{
            if (isHeader) {
                header = headList;
            } else {
                for (int i = 0; i < headList.size(); i++) {
                    header.add(ComponentConstants.COLUMN_PREFIX + (i+1));
                }
            }
        }
        return header;
    }

    /**
     * 复写这个方法
     * @return
     */
    @Override
    public NodeInfo get(){
        NodeInfo nodeInfo = NodeInfo.builder().name(nodeDTO.getName())
                .id(nodeDTO.getId()).rule(nodeDTO.getCode()).build();
        nodeInfo.setParam(analysis());
        //重设rule
        nodeInfo.setRule(nodeDTO.getCode());
        return nodeInfo;
    }
}
